package work.calculate;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.h819.core.commons.Configurations;
import com.h819.core.commons.MyLangUtils;
import com.h819.core.db.MyDbUtils;
import com.h819.core.utils.CharSetUtils;
import com.h819.core.utils.date.MyDateUtilsExtend;

/**
 * @Title: Oracle.java
 * @Description: TODO(CalculateOracle 数据库常用统计操作)
 * @author H819
 * @date 2011-1-18
 * @version V1.0
 */
public class CalculateOracle {

	private Logger log = Logger.getLogger(CalculateOracle.class);
	PropertiesConfiguration conf = Configurations
			.getInstance("work.properties");
	private QueryRunner runner = new QueryRunner();
	private Connection conn = MyDbUtils.getInstance("work.properties")
			.getConnection("oracle.jdbc.driver.OracleDriver",
					conf.getString("jdbc.oracle.work.235.readonly.url"),
					conf.getString("jdbc.oracle.work.235.readonly.user"),
					conf.getString("jdbc.oracle.work.235.readonly.password"));

	private CharSetUtils charSetUtils = new CharSetUtils();

	/**
	 * 
	 * (何陆翼)市局任务：查询北京市企业，参与标准制、修订情况 。参考下面的中关村统计方法，再次进行 sql 语句修改
	 * 
	 */
	private void searchBeijingCompany() {

		// 指定年分
		String year = "2010";
		// 包含企业名称的文件，每个企业一行
		File fread = new File("d:\\f.txt");

		// 如果保存为 UTF-8 格式，第一行为空行，会把该行判断为有内容，不知道为什么
		if (!charSetUtils.getFileCharacterEncoding(fread).equals("GB2312")) {

			log.info("file '" + fread.getName()
					+ "' 不是 ASCII 格式, 在 windows 下面另存为 ASCII 格式后在进行计算.");
			return;

		}

		// 查询结果
		List<Object[]> searchResult;

		// 最后结果
		// List<String> result = new ArrayList<String>();

		// 包含公司名称的集合
		List<String> company = new ArrayList<String>();

		try {

			company = FileUtils.readLines(fread, "GBK");

		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		// 逐一循环企业
		for (String s : company) {
			// like ; not like
			String searchSql = "select standard_code,namecn,replaced_standard,issue_time,act_time,draft_dept,text_address "
					+ "from standard.st_standard "
					+ "where standard_code like '%-"
					+ year
					+ "' and draft_dept like '%" + s.trim() + "%'";

			log.info(searchSql);

			String[] rtemp = new String[4];
			String tempstr = "";

			try {

				searchResult = runner.query(conn, searchSql,
						new ArrayListHandler());

				// 主要:起草单位排名第一，其他的是参与。

				// ===

				// 主要制定
				int mainZhiding = 0;
				// 主要修订
				int mainXiuding = 0;
				// 参与制定
				int assisZhiding = 0;
				// 参与修订
				int assisXiuding = 0;

				String standard_code = null;
				String namecn = null;
				String replaced_standard = null;
				String draft_dept = null;

				for (Object[] obj : searchResult) {

					if (obj[0] != null)
						standard_code = obj[0].toString();

					if (obj[1] != null)
						namecn = obj[1].toString();

					if (obj[2] != null)
						replaced_standard = obj[2].toString();

					if (obj[5] != null)
						namecn = obj[5].toString();

					if (obj[0] != null)
						draft_dept = obj[0].toString();

					// 判断起草单位
					if (draft_dept != null) {

						// 替换所有不规范字符
						draft_dept = draft_dept.replaceAll(",", ";")
								.replaceAll("，", ";").replaceAll(" ", ";")
								.replaceAll("　", ";");

						// 起草单位数组
						String[] scontiner = StringUtils.split(draft_dept, ";");

						int size = scontiner.length;

						// 只有 一个起草单位，该单位是：主导制定和主导修订
						if (size == 1)
							if (replaced_standard != null
									&& !replaced_standard.equals(""))
								mainXiuding++;
							else
								mainZhiding++;

						// 两个以上起草单位
						else {

							if (scontiner[0].equals(s))// 如果在第一位，主导制定和主导修订

								if (replaced_standard != null
										&& !replaced_standard.equals(""))
									mainXiuding++;
								else
									mainZhiding++;
							else {// 如果不在第一位，主导制定和主导修订
								if (replaced_standard != null
										&& !replaced_standard.equals(""))
									assisXiuding++;
								else
									assisZhiding++;
							}

						}

					}

				}

				log.info("主导制定 :" + mainZhiding);
				log.info("主导修订 :" + mainXiuding);
				log.info("参与制定 :" + assisZhiding);
				log.info("参与修订 :" + assisXiuding);
				log.info("合计 ："
						+ (mainZhiding + mainXiuding + assisZhiding + assisXiuding));

			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				DbUtils.closeQuietly(conn);
			}

			System.out.println(tempstr);

		}

	}

	/**
	 * 中关村任务：查询指定企业，参与标准制、修订情况
	 * 
	 * @param fileInput
	 *            包含企业名称的 txt 文件，每个企业名称一行。
	 * @param yearBegin
	 *            ，格式为 2012-01-01
	 * @param yearEnd
	 *            ，格式为 2012-01-01
	 * @return 结果为 txt 文件，用 excel 导入文本数据的方式导入，分隔符选择为"@"
	 */

	private void searchZgcCompany(File fileInput, String yearBegin,
			String yearEnd) {

		// 区分不同 excel 列
		String splitExcelTag = "@";

		int printNum = 0;

		// 包含企业名称的文件，每个企业一行
		// File fileInput = new File("d:\\f2.txt");

		if (!fileInput.exists()) {
			log.info("file '" + fileInput.getName() + "' does not exists.");
			return;
		}

		if (!FilenameUtils.getExtension(fileInput.getName()).equals("txt")) {
			log.info("fileInput is not 'txt' file type.");
			return;
		}

		// 如果保存为 UTF-8 格式，第一行为空行，会把该行判断为有内容，不知道为什么，所以不用 UTF-8 格式。
		// 在 windows 下面，另外为 ASCII 格式，用 GB2312 读取，不会乱码。
		if (!charSetUtils.getFileCharacterEncoding(fileInput).equals("GB2312")) {

			log.info("file '" + fileInput.getName()
					+ "' 不是 ASCII 格式, 在 windows 下面另存为 ASCII 格式后在进行计算.");

			return;
		}

		// 输出的结果，之后用 excel 打开
		File fwrite = new File(fileInput.getParent() + "\\"
				+ FilenameUtils.getBaseName(fileInput.getName()) + "_out.txt");

		// 如果有日期现在，验证日期格式
		if (yearBegin != null && yearEnd != null) {

			// 在这里可以验证时间格式

			if (!yearBegin.matches(MyDateUtilsExtend.datePatternReg)
					|| !yearEnd.matches(MyDateUtilsExtend.datePatternReg)) {

				log.info("日期不满足格式");

				return;
			}

		}

		// 查询结果
		List<Object[]> searchResult;

		// 临时保存结果
		List<String[]> result = new ArrayList<String[]>();

		// 最后输出结果
		List<String> resultOut = new ArrayList<String>();

		// 包含公司名称的集合
		List<String> companyList = new ArrayList<String>();
		try {
			//
			companyList = FileUtils.readLines(fileInput, "GBK");
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		// excle 第一行，标题
		result.add(new String[] { "公司名称", "参与标准", "发布日期", "编写单位", "参与标准数量" });

		// 逐一循环企业
		for (String companyName : companyList) {
			// like ; not like

			printNum++;
			log.info(printNum + " : " + companyName);

			if (StringUtils.isEmpty(companyName)
					|| StringUtils.isBlank(companyName))
				continue;

			// 指定年份区间
			String searchSql = "select standard_code,namecn,replaced_standard,issue_time,act_time,draft_dept,text_address "
					+ "from standard.st_standard "
					+ "where issue_time between to_date('"
					+ yearBegin
					+ "','yyyy-mm-dd') and to_date('"
					+ yearEnd
					+ "','yyyy-mm-dd') and "
					+ "draft_dept like '%"
					+ companyName.trim() + "%'";

			// 指定无年份限制
			String searchSql2 = "select standard_code,namecn,replaced_standard,issue_time,act_time,draft_dept,text_address "
					+ "from standard.st_standard "
					+ "where draft_dept like '%"
					+ companyName.trim() + "%'";

			if (yearBegin == null && yearEnd == null)
				searchSql = searchSql2;

			log.info(searchSql);

			try {

				searchResult = runner.query(conn, searchSql,
						new ArrayListHandler());

				// 企业名称 companyName

				String[] rtemp = null;

				// 参与数量
				int count = searchResult.size();
				String countStr = String.valueOf(count);
				// 该单位没有参与制定
				if (countStr.equals("0")) {
					rtemp = new String[5];
					// 公司名称
					rtemp[0] = companyName;
					// 参与标准号
					rtemp[1] = "";
					// 发布日期
					rtemp[2] = "";
					// 编写单位
					rtemp[3] = "";
					// 参与标准数量
					rtemp[4] = "0";
					result.add(rtemp);
					continue;

				}
				// 单个企业，制定多个标准，多个不同的起草单位，不同的发布日期
				// 分别包装为一个数组

				for (int i = 0; i < count; i++) {

					Object[] obj = searchResult.get(i);

					rtemp = new String[5];

					// standard_code,namecn,replaced_standard,issue_time,act_time,draft_dept,text_address

					/**
					 * 每条记录包装为一个数组
					 * 
					 * */
					// 公司名称
					if (i == 0)
						rtemp[0] = companyName;
					else
						rtemp[0] = "";

					// 处理标准号
					if (obj[0] != null) {
						// 参与标准号，标准名称
						if (obj[1] != null)
							rtemp[1] = obj[0].toString() + "("
									+ obj[1].toString() + ")";
						else
							rtemp[1] = obj[0].toString();
					} else
						rtemp[1] = "";

					// 处理发布日期: obj[3]
					if (obj[3] != null) {
						// 发布日期
						rtemp[2] = obj[3].toString();
					} else
						rtemp[2] = "";

					// 处理编写单位: obj[5]
					if (obj[5] != null) {
						// 编写单位
						rtemp[3] = obj[5].toString();
					} else
						rtemp[3] = "";

					// 参与标准合计数
					if (i == count - 1)
						rtemp[4] = countStr;
					else
						rtemp[4] = "";

					result.add(rtemp);

				}

			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// log.info(results);

		}

		DbUtils.closeQuietly(conn);

		// 每个单位名称循环
		for (String[] ref : result) {
			String temps = "";
			for (String str : ref)
				temps = temps + splitExcelTag + str;
			temps = StringUtils.removeStart(temps, splitExcelTag);
			resultOut.add(temps);
			// 打印测试
			// log.info(temps);

		}

		// 输出结果
		try {
			FileUtils.writeLines(fwrite, resultOut);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 判断给定的字符串，是否包含字符串数组中的任意元素。
	 * 
	 * @param str
	 * @param searchString
	 * @return
	 */
	private boolean contains(String str, String[] searchString) {

		boolean is = false;

		for (String s : searchString)
			if (StringUtils.contains(str, s)) {
				is = true;
				break;
			}

		return is;

	}

	private String getSQL(String[] str) {

		return null;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		CalculateOracle ora = new CalculateOracle();
		// ora.searchZgcCompany(new File("d:\\1.txt"), "2011-01-01",
		// "2011-11-08");
		System.out.println("hello");
		ora.searchZgcCompany(new File("d:\\2012.txt"), "2012-01-01",
				"2012-12-31");

	}

}
